using AutoFixture;
using AutoFixture.Xunit2;
using FluentAssertions;
using Moq;
using SG3L_RAG.Domain.Entities;
using SG3L_RAG.Domain.Repositories;

namespace SG3L_RAG.UnitTests;

/// <summary>
/// 单元测试基类，提供通用的测试设施
/// </summary>
public abstract class TestBase
{
    protected readonly IFixture Fixture;
    protected readonly Mock<IRepository<User>> MockUserRepository;
    protected readonly Mock<IRepository<Document>> MockDocumentRepository;
    protected readonly Mock<IRepository<Conversation>> MockConversationRepository;
    protected readonly Mock<IRepository<Message>> MockMessageRepository;
    protected readonly Mock<IRepository<DocumentChunk>> MockDocumentChunkRepository;
    protected readonly Mock<IRepository<Permission>> MockPermissionRepository;
    protected readonly Mock<IRepository<Log>> MockLogRepository;
    protected readonly Mock<IRepository<Statistics>> MockStatisticsRepository;

    protected TestBase()
    {
        Fixture = new Fixture();
        
        // 配置 AutoFixture 以处理循环引用
        Fixture.Behaviors.Remove(new ThrowingRecursionBehavior());
        Fixture.Behaviors.Add(new OmitOnRecursionBehavior());
        
        // 初始化 Repository Mock
        MockUserRepository = new Mock<IRepository<User>>();
        MockDocumentRepository = new Mock<IRepository<Document>>();
        MockConversationRepository = new Mock<IRepository<Conversation>>();
        MockMessageRepository = new Mock<IRepository<Message>>();
        MockDocumentChunkRepository = new Mock<IRepository<DocumentChunk>>();
        MockPermissionRepository = new Mock<IRepository<Permission>>();
        MockLogRepository = new Mock<IRepository<Log>>();
        MockStatisticsRepository = new Mock<IRepository<Statistics>>();
    }

    /// <summary>
    /// 创建测试用户
    /// </summary>
    protected User CreateTestUser(string username = "testuser", string role = "user")
    {
        return User.Create(username, "password123", $"{username}@test.com", "13800138000", role);
    }

    /// <summary>
    /// 创建测试文档
    /// </summary>
    protected Document CreateTestDocument(Guid uploaderId, string name = "test.txt")
    {
        return Document.Create(name, name, "txt", 1024, uploaderId, "pending", "private");
    }

    /// <summary>
    /// 创建测试对话
    /// </summary>
    protected Conversation CreateTestConversation(Guid userId)
    {
        return Conversation.Create(userId);
    }
}

/// <summary>
/// AutoData 特性，用于自动生成测试数据
/// </summary>
public class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute() : base(() => new Fixture())
    {
    }
}
